<?php
// 给定一个含有 n 个正整数的数组和一个正整数 s ，找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组，并返回其长度。如果不存在符合条件的子数组，返回 0。
// https://leetcode-cn.com/problems/minimum-size-subarray-sum/solution/chang-du-zui-xiao-de-zi-shu-zu-by-leetcode-solutio/
class Solution {
    /**
     * @param Integer $s
     * @param Integer[] $nums
     * @return Integer
     */
    /**
     * @param $s
     * @param $nums
     * @return int|mixed
     *
     *
     */
    function minSubArrayLen($s, $nums) {
        if (empty($nums)) {
            return 0;
        }
        $input_nums_len = count($nums);
        $start = 0;
        $winLen = PHP_INT_MAX;
        $sum = 0;
        for ($end=0; $end<$input_nums_len; $end++) {
            $sum += $nums[$end];
            // 发现大于等于目标数，回溯
            if ($sum >= $s) {
                // 从之前维护的最小窗口的起始索引开始一个个去掉  看是否满足条件
                while ($sum >= $s) {
                    $len = $end - $start + 1;
                    $winLen = min($winLen, $len);
                    $sum -= $nums[$start];
                    $start++;
                }
            }
        }
        return $winLen == PHP_INT_MAX ? 0 : $winLen;
    }
}
// 定义两个指针start 和 end 分别表示子数组的开始位置和结束位置，维护变量 sum 存储子数组中的元素和（即从 nums[start] 到 nums[end] 的元素和）。
// 初始状态下，start 和 end 都指向下标 0，sum 的值为 0。
// 每一轮迭代，将 nums[end] 加到 sum，如果sum≥s，则更新子数组的最小长度（此时子数组的长度是 end−start+1），然后将 nums[start] 从 sum 中减去并将 start 右移，直到 sum<s，在此过程中同样更新子数组的最小长度。在每一轮迭代的最后将end 右移。